#include "../include/PureWebPage.hpp"


#include <sstream>
#include <iostream>
#include <algorithm>

using std::cout;
using std::endl;
using std::istringstream; 
using std::pair;


PureWebPage::PureWebPage(string& doc){

    const string DOCID_BEGIN = "<docid>";
    const string DOCID_END= "</docid>";

    const string LINK_BEGIN = "<url>";
    const string LINK_END= "</url>";

    const string TITLE_BEGIN = "<title>";
    const string TITLE_END= "</title>";

    const string CONTENT_BEGIN = "<content>";
    const string CONTENT_END= "</content>";

    int posBegin = 0, posEnd = 0;

    //载入docId
    posBegin = doc.find(DOCID_BEGIN, 0) + DOCID_BEGIN.size();//find返回要查找的字符串的开始位置
    posEnd = doc.find(DOCID_END, posBegin);

    _docId = atoi(doc.substr(posBegin, posEnd - posBegin).c_str());

    //载入docLink
    posBegin = doc.find(LINK_BEGIN, posEnd) + LINK_BEGIN.size();
    posEnd = doc.find(LINK_END, posBegin);

    _docLink = doc.substr(posBegin, posEnd - posBegin);

    //载入docTitle
    posBegin = doc.find(TITLE_BEGIN, posEnd) + TITLE_BEGIN.size();
    posEnd = doc.find(TITLE_END, posBegin);

    //test
    /* cout << "title posBegin = " << posBegin << endl; */
    /* cout << "title posEnd = " << posEnd << endl; */

    _docTitle = doc.substr(posBegin, posEnd - posBegin);

    //载入docDescription
    posBegin = doc.find(CONTENT_BEGIN, posEnd) + CONTENT_BEGIN.size();
    posEnd = doc.find(CONTENT_END, posBegin);

    //test
    /* cout << "content posBegin = " << posBegin << endl; */
    /* cout << "content posEnd = " << posEnd << endl; */

    _docContent = doc.substr(posBegin, posEnd - posBegin);

    _docSummary = "";

    //test
    /* cout << "docId = " << _docId << endl; */
    /* cout << "docLink = " << _docLink << endl; */
    /* cout << "docTitle = " << _docTitle << endl; */
    /* cout << "docContent = " << _docContent << endl; */

}

bool compare(const pair<string, int> &lhs, const pair<string, int> &rhs){
    return lhs.second > rhs.second;
}


string& PureWebPage::summary(const vector<string> & queryWords){
    string line;
    const string ZH_SPLIT = "。";
    const int ZH_SIZE = 3;

    vector<int> spacePos;
    int prePos = 0, curPos = 0;

    while(1){//每次向后移动3个字符查找句号
        curPos = _docContent.find(ZH_SPLIT, prePos);
        if(curPos == std::string::npos) break;//找不到句号就结束循环
        spacePos.push_back(curPos);//把找到的句号下标放入 vector<int> spacePos
        prePos = curPos + ZH_SIZE;
    }
    if(spacePos.empty()){//如果存放句号的容器为空，就返回文档内容作为摘要
        return _docContent;
    }

    spacePos.push_back(_docContent.size());//把文章最后的句号的位置加进容器里
    vector<pair<string, int>> lineAndFreq;//出现查询词的句子，词频

    for(int i = 1; i < spacePos.size(); ++i){
        string line;
        int freq = 0;
        line.clear();
        line = _docContent.substr(spacePos[i-1] + ZH_SIZE, spacePos[i] - spacePos[i-1]);

        //累计查询词在句子中出现的频率
        for(auto &word : queryWords){
            freq += findKeyWords(word, line);
        }
        // cout << line << "\n"
        //     << freq << "\n";
        lineAndFreq.push_back(make_pair(line, freq));
    }

    //排序
    sort(lineAndFreq.begin(), lineAndFreq.end(), compare);
    // cout << lineAndFreq.size() << endl;

    //挑选前三句
    _docSummary.clear();
    _docSummary += lineAndFreq[0].first;
    //如果有2句，且第2句的词频>0，把第2句也加上
    if(lineAndFreq.size() >= 2 && lineAndFreq[1].second > 0){
        _docSummary += lineAndFreq[1].first;
    }
    if(lineAndFreq.size() >= 3 && lineAndFreq[2].second > 0){
        _docSummary += lineAndFreq[2].first;
    }
    return _docSummary;

}

//找出句子中出现的关键词，在其左右加上【】以突出显示，返回关键词出现的次数
int PureWebPage::findKeyWords(const string word, string& line){
    const string LEFT_TAG = "【";
    const string RIGHT_TAG = "】";
    const int TAG_SIZE = LEFT_TAG.size();
    int prePos = 0, curPos = 0;
    int freq = 0;
    size_t wordSize = word.size();
    while(1){
        curPos = line.find(word, prePos);
        if(curPos == std::string::npos){
            break;
        }

        line.insert(curPos, LEFT_TAG);

        line.insert(curPos + wordSize + TAG_SIZE, RIGHT_TAG);

        ++freq;
        prePos = curPos + wordSize + 2 * TAG_SIZE;
    }
    return freq;
}
